package com.tlias.AOP;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

// 使用 Lombok 的 @Slf4j 注解，自动生成日志记录器 log
@Slf4j
// 使用 Spring 的 @Component 注解，表示该类是一个 Spring 组件，会被自动扫描并注册为 Bean
//@Component
// 使用 AspectJ 的 @Aspect 注解，表示该类是一个切面类，用于定义 AOP 拦截逻辑
//@Aspect
public class DomeAspect {
    //  定义切点 pointcut，用于匹配 com.tlias.service.impl 包下的所有方法
    //@Pointcut抽取公共切点表达式配合pointcut()方法,pointcut自己定义都
    @Pointcut("execution(* com.tlias.service.impl.*.*(..))")
    public void pointcut() {}//  定义切点
//    @Around("execution(* com.tlias.service.impl.*.*(..))")

    // 定义一个方法 recordTime，用于统计目标方法执行耗时
    // 该方法将作为 AOP 切面中的通知（Advice），类型为环绕通知（Around Advice）
    @Around("pointcut()")//  定义通知的切点
    public Object recordTime(ProceedingJoinPoint joinPoint) {
        // 获取当前时间戳（单位：毫秒），作为开始时间
        long start = System.currentTimeMillis();

        try {
            // 调用 joinPoint.proceed() 执行被拦截的目标方法
            // 返回值 result 表示目标方法的返回结果
            Object result = joinPoint.proceed();

            // 再次获取当前时间戳，作为结束时间
            long end = System.currentTimeMillis();

            // 计算并打印目标方法的执行耗时
            log.info("本次操作耗时{}ms", end - start);

            // 返回目标方法的执行结果
            return result;
        } catch (Throwable e) {
            // 如果目标方法抛出异常，则将其封装为 RuntimeException 抛出
            throw new RuntimeException(e);
        }
    }
}
